package com.jahe.learn.nio;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;

/**
 * MappedByteBuffer的使用，只需要在内存中操作文件的数据。后台自动完成读写
 * @author: jahe.lai
 * @create: 2019-12-25 09:45
 */
public class MappedBufferDemo {

    public static void main(String[] args) {
        RandomAccessFile accessFile = null;
        try {
            accessFile = new RandomAccessFile("mapped-demo.txt", "rw");
            FileChannel fileChannel = accessFile.getChannel();

            MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 5);
            mappedByteBuffer.put(0, (byte)'a');
            mappedByteBuffer.put(3, (byte)'b');

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                accessFile.close();
            } catch (Exception ex) {

            }
        }
    }

    /**
     * 字符编码的用例，增加对中文的支持
     */
    public static void testCharset() {
        RandomAccessFile accessFile = null;
        RandomAccessFile writeFile = null;
        try {
            accessFile = new RandomAccessFile("mapped-demo.txt", "r");
            writeFile = new RandomAccessFile("mapped-demo-out.txt", "rw");
            FileChannel fileChannel = accessFile.getChannel();
            FileChannel outChannel = writeFile.getChannel();

            long inputLength = new File("mapped-demo.txt").length();

            MappedByteBuffer inputData = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, inputLength);

            Charset charset = Charset.forName("utf-8");
            CharsetDecoder decoder = charset.newDecoder();
            CharsetEncoder encoder = charset.newEncoder();

            CharBuffer charBuffer = decoder.decode(inputData);
            ByteBuffer byteBuffer = encoder.encode(charBuffer);

            outChannel.write(byteBuffer);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                accessFile.close();
                writeFile.close();
            } catch (Exception ex) {

            }
        }
    }
}
